/*
监听主机的80端口，把客户端的请求打印到标准输出
v2版本
	添加对客户端的响应，把客户端的请求内容返回给客户端
*/

package main

import (
	"log"
	"net"
//	"os"
	"fmt"
	"time"
	"sync"
	"strings"
)
var wg sync.WaitGroup
var sum int
var connBox = make([]*net.TCPConn, 100)
var connRead = make([]byte, 200)

func main() {
//	ip := net.IPv4(127,0,0,1)
	ip := net.IPv4(0,0,0,0)
	laddr := net.TCPAddr{
		IP: ip,
		Port: 80,
	}
	ln, err := net.ListenTCP("tcp4", &laddr)
	myerr(err)
	defer ln.Close()
	for {
		<-time.Tick(1*time.Millisecond)
		fmt.Println("Dbug-> Accept Begin")
		conn, err := ln.AcceptTCP()
		connBox = append(connBox, conn)
		_, err = conn.Read(connRead)
		if err != nil {
			log.Println("main connRead err")
		}
		fmt.Println("main-connRead: ", string(connRead))
		go logshow(conn)
	}
}

func broadcast() {
	fmt.Println("Dbug-> broadcast-Begin")
	fmt.Println("read-from-conn", string(connRead))
//给接收到的信息加一个“hello”头的字符串
	tmp := "hello " + string(connRead)
	r := strings.NewReader(tmp)
	b := make([]byte, 10)
	r.Read(b)
	fmt.Println("broadcast-b: ", string(b))
//广播的逻辑

	for i:=0;;i++ {
		if connBox[i] == nil{
			fmt.Println("break")
		}
		fmt.Println("broadcast-connBox[i]-Write begin")
		_, err := connBox[i].Write(b)
		if err != nil {
			fmt.Println("broadcast-c.Write err")
		}
		fmt.Println("broadcast-c.Write seccess")
	}
/*
	for n, c := range connBox { 	//这里要用一个可以反复读的结构
	fmt.Println("broadcast-connBox: ", n)
	_, err := c.Write(b)
	if err != nil {
		fmt.Println("broadcast-c.Write err")
	}
	fmt.Println("broadcast-c.Write seccess")
	}
*/
	wg.Done()
}

func logshow(c *net.TCPConn) {
	sum++
	log.Println("resoved request RemoteAddr:", c.RemoteAddr().String(), "sum:", sum)
	log.Println("resoved request RemoteAddr:", c.RemoteAddr().Network(), "sum:", sum)
	log.Printf("logshow-resove content: %s", string(connRead)) 
	wg.Add(1)
	go broadcast()
	wg.Wait()
//	c.Close()	//暂时先不考虑关闭链接
	log.Println("---->this request is over---->")
}

func myerr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

/*
func response(c *net.TCPConn, b []byte) {
	fmt.Println("Dbug-> response begin")
	_, err := c.Write(b)
	myerr(err)
	fmt.Println("Dbug-> response content: ", string(b))
	fmt.Println("Dbug-> response over")
	wg.Done()
}
*/
